package com.hjk.common.utils.reflect;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.function.Supplier;

/**
 * 失败重试工具类
 *
 * @author huangjunkai
 * @version 1.0
 * @date 2020/5/29 16:42
 */
@Component
public class RetriesUtils {
    private static final Logger log = LoggerFactory.getLogger(RetriesUtils.class);
    /**
     * 重试次数
     */
    @Value("${biMobile.retries:5}")
    public int retries = 5;

    //@Autowired
    //private MessageClient messageClient;

    /**
     * 重试方法,默认重试3次
     *
     * @param retriesCount 重试次数
     * @param business     业务类型
     * @param supplier     方法
     */
    private static <T> T retriesMethod(int retriesCount, String business, Supplier supplier) {
        try {
            boolean result = (Boolean) supplier.get();
            //方法执行失败进入重试
            if (result) {
                for (int count = 1; count <= retriesCount; count++) {
                    //方法重试
                    log.info("=======方法[{}] 第{}次重试中========", business, count);
                    boolean success = (Boolean) supplier.get();
                    //执行成功则结束
                    if (!success) {
                        log.info("=======方法[{}] 第{}次重试成功========", business, count);
                        break;
                    }

                }
            }
        } catch (Exception e) {
            log.error("=======重试方法[{}]失败错误=======", business, e);
        }
        return null;
    }

    /**
     * 重试方法,默认重试3次
     *
     * @param business 业务类型
     * @param runnable 方法
     */
    public void execute(String business, String key, Runnable runnable) {
        execute(retries, business, key, runnable);
    }

    /**
     * 重试方法
     *
     * @param retriesCount 重试次数
     * @param business     业务类型
     * @param runnable     方法
     */
    public void execute(int retriesCount, String business, String key, Runnable runnable) {
        retriesMethod(retriesCount, business, () -> {
            try {
                runnable.run();
                return false;
            } catch (Exception e) {
                log.error("=======执行[ {} : {} ]方法失败 =======", business, key, e);
//                messageClient.sendAppMessage(business, key, e.getMessage());
                return true;
            }
        });

    }


    public static void main(String[] args) {
        RetriesUtils retriesUtils = new RetriesUtils();
        retriesUtils.execute("失败重试","1", () -> {
            int i = 1 / 0;
        });

        retriesUtils.execute("成功转型", "1", () -> {
            System.out.println(1111);
        });

    }

}
